﻿using System;
using System.Collections.Generic;
using System.IO;

namespace CsvReader {
    public class CsvReader {

        public static IEnumerable<string[]> Read(string filename) {
            string[] lines = GetLines(filename);
            return ProcessLines(lines);
        }

        private static string[] GetLines(string filename) {
            var lines = File.ReadAllLines(filename);
            if (0 == lines.Length) {
                throw new EmptyFileException();
            }
            return lines;
        }

        internal static string[][] ProcessLines(string[] lines) {
            var exactLength = ProcessControlRecord(lines[0]);
            var csvData = new string[lines.Length][];
            for (var i = 0; i < lines.Length; i++) {
                csvData[i] = ProcessSingleRecord(lines[i], exactLength);
            }
            return csvData;
        }

        internal static int ProcessControlRecord(string line) {
            string[] data = GetFields(line);
            foreach (var s in data) {
                if (String.IsNullOrEmpty(s)) {
                    throw new EmptyFieldException();
                }
            }
            return data.Length;
        }

        internal static string[] ProcessSingleRecord(string line, int exactLength) {
            var fields = GetFields(line);
            string[] data = GetDataFromFields(fields, exactLength);
            data = FillUpRestOfFieldsToExactLength(fields.Length, exactLength, data);

            return data;
        }

        private static string[] FillUpRestOfFieldsToExactLength(int fieldLength, int exactLength, string[] data) {
            for (var i = fieldLength; i < exactLength; i++) {
                data[i] = String.Empty;
            }
            return data;
        }

        private static string[] GetDataFromFields(string[] fields, int exactLength) {
            var data = new string[exactLength];
            for (var i = 0; i < fields.Length; i++) {
                data[i] = String.IsNullOrEmpty(fields[i]) ? String.Empty : fields[i];
            }
            return data;
        }

        private static string[] GetFields(string line) {
            var data =  line.Split(',');
            for (var i = 0; i < data.Length; i++) {
                data[i] = data[i].Trim();
            }
            return data;
        }
    }
}
